#include "Widget.h"
#include "ui_Widget.h"
#include <QDir>
#include <QFileInfo>
#include <QFile>
#include <QTimer>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget),
    _mjpgRunner(NULL),
    _timer(NULL)
{
    ui->setupUi(this);
    searchForMjpgSreamer();
    loadVideoDevices();
    qDebug()<<"_mjpgStreamerPath"<<_mjpgStreamerPath;

    _timer = new QTimer(this);
    connect(_timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
    _timer->setSingleShot(true);
    _timer->setInterval(1000);
}

Widget::~Widget()
{
    stop();
    delete ui;
}

void Widget::searchForMjpgSreamer()
{
    static const char *prefix[] = {
        "./", "../", "./mjpg_streamer/", "../mjpg_streamer/",
        "/root/mjpg_streamer/", "/Applicatoin/mjpg_streamer/",
    };
    for(uint i = 0; i < sizeof(prefix) / sizeof(prefix[0]); i++)
    {
        QFileInfo fi(QString("%1mjpg_streamer").arg(prefix[i]));
        qDebug()<<"search for"<<fi.absoluteFilePath();
        if(fi.isFile() && fi.isExecutable())
        {
            _mjpgStreamerPath = prefix[i];
            break;
        }
    }
}

void Widget::loadVideoDevices()
{
    ui->videoDevList->clear();
    int defIndex = -1;
    QDir videoDir("/sys/class/video4linux");
    videoDir.setFilter(QDir::AllEntries);
    QFileInfoList list = videoDir.entryInfoList(QStringList()<<"video*");
    for(int i = 0; i < list.count(); i++)
    {
        const QFileInfo &info = list.at(i);
        QString namePath = info.absoluteFilePath()+"/name";
        qDebug()<<"Found a namePath:"<<namePath;
        if(!QFile::exists(namePath))
        {
            qDebug()<<"Not Exists!!!";
            continue;
        }
        QFile f(namePath);
        if(!f.open(QIODevice::ReadOnly))
        {
            qDebug()<<"Can't Open!!!";
            continue;
        }
        QByteArray name = f.readAll();
        f.close();
        name = name.trimmed();
        ui->videoDevList->addItem(
                    QString("%1 (%2)").arg(info.fileName()).arg(QString(name)),
                    QString("/dev/%1").arg(info.fileName()));
        qDebug()<<"name:"<<name;
        if(defIndex == -1)
        {
            if(name.contains("Cam") || name.contains("cam"))
                defIndex = ui->videoDevList->count() - 1;
        }
    }
    if(defIndex != -1)
        ui->videoDevList->setCurrentIndex(defIndex);
}

void Widget::start()
{
    stop();
    _mjpgRunner = new QProcess(this);
    connect(_mjpgRunner, SIGNAL(error(QProcess::ProcessError)),
            this, SLOT(onError(QProcess::ProcessError)));
    connect(_mjpgRunner, SIGNAL(finished(int,QProcess::ExitStatus)),
            this, SLOT(onFinished(int,QProcess::ExitStatus)));
    connect(_mjpgRunner, SIGNAL(readyReadStandardError()),
            this, SLOT(onReadyReadStandardError()));
    connect(_mjpgRunner, SIGNAL(readyReadStandardOutput()),
            this, SLOT(onReadyReadStandardOutput()));
    connect(_mjpgRunner, SIGNAL(started()),
            this, SLOT(onStarted()));
    QProcessEnvironment env;
    env = _mjpgRunner->processEnvironment();
    QString ldPath =env.value("LD_LIBRARY_PATH");
    if(!ldPath.isEmpty())
        ldPath.append(":");
    ldPath.append(_mjpgStreamerPath);
    _mjpgRunner->setProcessEnvironment(env);
    QString httpArg = QString("%1output_http.so -p %2 -w /root/www")
            .arg(_mjpgStreamerPath).arg(ui->portEdit->value());
    QString uvcArg = QString("%1input_uvc.so -y -r %2 -d %3")
            .arg(_mjpgStreamerPath).arg(ui->resolutionList->currentText())
            .arg(ui->videoDevList->itemData(ui->videoDevList->currentIndex()).toString());
    _mjpgRunner->start(_mjpgStreamerPath+"mjpg_streamer",
                       QStringList()
                       <<"-o"<<httpArg
                       <<"-i"<<uvcArg
                       );
}

void Widget::stop()
{
    ui->videoWidget->stop();
    ui->videoWidget->clear();
    if(_mjpgRunner == NULL)
        return;
    _mjpgRunner->disconnect();
    _mjpgRunner->kill();
    _mjpgRunner->waitForFinished();
    _mjpgRunner->deleteLater();
    _mjpgRunner = NULL;
    ui->paramWidget->setEnabled(true);
    ui->openCloseBtn->setText(tr("Open"));
}

void Widget::onError(QProcess::ProcessError error)
{
    QString errLog = QString("<span style=\"color:red;\">error code %1</span>")
            .arg(int(error));
    ui->logEdit->append(errLog);
    stop();
}

void Widget::onFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
    QString log = QString("<span style=\"color:black;\">mjpg_streamer finished with %1 %2</span>")
            .arg(exitCode).arg(int(exitStatus));
    ui->logEdit->append(log);
    stop();
}

void Widget::onReadyReadStandardError()
{
    QByteArray errLog = _mjpgRunner->readAllStandardError();
    ui->logEdit->append(QString("<span style=\"color:red;\">%1</span>")
                        .arg(QString(errLog)));
}

void Widget::onReadyReadStandardOutput()
{
    QByteArray log = _mjpgRunner->readAllStandardError();
    ui->logEdit->append(QString("<span style=\"color:black;\">%1</span>")
                        .arg(QString(log)));
}

void Widget::onStarted()
{
    ui->paramWidget->setEnabled(false);
    ui->openCloseBtn->setText(tr("Close"));
    ui->videoWidget->start("127.0.0.1", ui->portEdit->value());
//    _timer->start();
}

void Widget::onTimeout()
{
//    ui->videoWidget->start("127.0.0.1", ui->portEdit->value());
}

void Widget::on_openCloseBtn_clicked()
{
    if(_mjpgRunner == NULL)
        start();
    else
        stop();
}

void Widget::on_quitBtn_clicked()
{
    stop();
    close();
}
